package com.mpgame.common.connection;

import com.mpgame.common.network.GrpcClient;
import com.mpgame.common.utils.Log;

import io.grpc.ConnectivityState;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.LinkedBlockingQueue;

public class GrpcConnectionPool {
    private final String serviceName;
    private final String address;
    private final int maxSize;
    private final int minSize;

    private volatile boolean initialized = false;

    private final BlockingQueue<GrpcClient> availableConnections;
    private final AtomicInteger currentSize = new AtomicInteger(0);
    private final AtomicInteger activeConnections = new AtomicInteger(0);

    public GrpcConnectionPool(String serviceName, String address, int minSize, int maxSize) {
        this.serviceName = serviceName;
        this.address = address;
        this.minSize = minSize;
        this.maxSize = maxSize;
        this.availableConnections = new LinkedBlockingQueue<>(maxSize);
        firstInitialize();
        Log.info("连接池初始化完成: " + serviceName + ", 最小连接数: " + minSize + ", 最大连接数: " + maxSize);
    }
    private synchronized void firstInitialize() {
        if (!initialized) {
            for (int i = 0; i < this.minSize; i++) {
                GrpcClient client = createConnection();
                if(client != null){
                    availableConnections.offer(client);
                }
            }
            initialized = true;
            Log.info("连接池资源准备完成：" + serviceName + ", 可用连接数：" + availableConnections.size());
        }
    }

    public GrpcClient borrowConnection() {
        firstInitialize();

        try {
            GrpcClient client = availableConnections.poll();
            if (client != null) {
                activeConnections.incrementAndGet();
                return client;
            }

            if (currentSize.get() < maxSize) {
                client = createConnection();
                if (client != null) {
                    activeConnections.incrementAndGet();
                    return client;
                }
            }

            client = availableConnections.take();
            activeConnections.incrementAndGet();
            return client;
        } catch (InterruptedException e) {
            Log.err("获取链接被中断：" + e.getMessage());
            Thread.currentThread().interrupt();
            return null;
        }
    }

    public void returnConnection(GrpcClient client) {
        if (client != null) {
            if (isConnectionHealthy(client)) {
                activeConnections.decrementAndGet();
                availableConnections.offer(client);
            } else {
                try {
                    client.shutdown();
                    currentSize.decrementAndGet();
                    if(currentSize.get() < maxSize){
                        GrpcClient newCli = createConnection();
                        if(newCli != null){
                            availableConnections.offer(newCli);
                        }
                    }
                    Log.debug("关闭不健康的连接并尝试重新创建：" + serviceName);
                } catch (Exception e) {
                    Log.err("关闭不健康连接失败：" + e.getMessage());
                }
            }
        }
    }

    private boolean isConnectionHealthy(GrpcClient client) {
        try {
            return client != null && client.isHealthy();
        } catch (Exception e) {
            Log.debug("GrpcConnectionPool::连接健康检测失败：" + e.getMessage());
            return false;
        }
    }

    private GrpcClient createConnection() {
        if (currentSize.get() >= maxSize) {
            return null;
        }

        try {
            GrpcClient client = new GrpcClient(address);
            currentSize.incrementAndGet();
            return client;
        } catch (Exception e) {
            Log.err("创建新连接失败：" + e.getMessage());
            return null;
        }
    }

    public boolean isHealthy(){
        // 没有任何连接
        if(currentSize.get() == 0){
            return false;
        }
        // 快速抽样检查前几个空闲连接
        int checked = 0;
        for(GrpcClient cli : availableConnections){
            if(cli != null && cli.isHealthy()){
                return true;
            }
            if(++checked >= 3){ // 只抽样最多3个
                break;
            }
        }
        // 抽样未发现健康连接，尝试临时创建一个测试
        GrpcClient test = createConnection();
        if(test != null){
            boolean ok = test.isHealthy();
            // 放回或关闭
            if(ok){
                returnConnection(test);
            }else{
                try { test.shutdown(); } catch (Exception ignore) {}
                currentSize.decrementAndGet();
            }
            return ok;
        }
        return false;
    }



    public void shutdown() {
        GrpcClient client;
        while ((client = availableConnections.poll()) != null) {
            client.shutdown();
        }
        Log.info("连接池已关闭：" + serviceName);
    }

    public String getStatus() {
        return String.format("连接池状态 [%s]: 总连接数=%d, 活跃连接数=%d, 可用连接数=%d",
                serviceName, currentSize.get(), activeConnections.get(), availableConnections.size());
    }
    public String getServiceName(){
        return serviceName;
    }

}
